#!/bin/bash

if ! { [ -e /sys/devices/system/cpu/cpufreq/policy0/scaling_governor ] &&
       [ -e /sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors ]; }; then
    exit 0
fi

EPP_AVAILABLE=""
if [ -e /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences ]; then
    EPP_AVAILABLE="1"
else
    EPP_AVAILABLE="0"
fi

# Check if governor exists for CPU
check_governor() {
    local GOVERNOR_TO_CHECK=$1
    local AVAILABLE_GOVERNORS
    AVAILABLE_GOVERNORS=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors)

    if [[ " $AVAILABLE_GOVERNORS " =~ [[:space:]]${GOVERNOR_TO_CHECK}[[:space:]] ]]; then
        return 0
    else
        return 1
    fi
}

# Set governor
set_governor() {
   local GOVERNOR_NAME=$1

   # Apply the governor to all policies
   for policy in /sys/devices/system/cpu/cpufreq/policy*; do
       if [ -e "$policy/scaling_governor" ]; then
           local CURRENT_GOVERNOR=$(cat "$policy/scaling_governor")
           if [ "$CURRENT_GOVERNOR" != "$GOVERNOR_NAME" ]; then
               echo $GOVERNOR_NAME > "$policy/scaling_governor" 2>/dev/null
           fi
       fi
   done
}

# Check if requested EPP is available
check_epp() {
    local PREFERENCE=$1
    local AVAILABLE_PREFERENCES
    AVAILABLE_PREFERENCES=$(cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences)

    # Check if the specified preference is available
    if [[ " $AVAILABLE_PREFERENCES " =~ [[:space:]]${PREFERENCE}[[:space:]] ]]; then
        return 0
    else
        return 1
    fi
}

# Set Energy Performance Preference
set_epp() {
    local PREFERENCE=$1

    for cpu in /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference; do
        if [ -e "$cpu" ]; then
            echo "$PREFERENCE" > "$cpu" 2>/dev/null
        fi
    done
}

# Set system default
set_default() {
    SYSTEM_GOVERNOR="$(/usr/bin/batocera-settings-get-master system.cpu.governor)"

    if check_governor "$SYSTEM_GOVERNOR"; then
        set_governor "$SYSTEM_GOVERNOR"
        # If EPP available set to default or performance as fallback
        if [ "$EPP_AVAILABLE" -eq 1 ]; then
            if check_epp "default"; then
                set_epp "default"
            elif check_epp "performance"; then
                set_epp "performance"
            fi
        fi
    fi
}

# Determine which Governors & if applicable EPP to set based on powermode setting
handle_powermode() {
    local POWERMODE_NAME=$1

    case "$POWERMODE_NAME" in
        "highperformance")
            set_governor "performance"
            if [ "$EPP_AVAILABLE" -eq 1 ]; then
                if check_epp "performance"; then
                    set_epp "performance"
                fi
            fi
            ;;
        "balanced")
            # Handle governor
            if check_governor "schedutil"; then
                set_governor "schedutil"
            elif check_governor "ondemand"; then
                set_governor "ondemand"
            elif check_governor "conservative"; then
                set_governor "conservative"
            elif check_governor "powersave"; then
                set_governor "powersave"
            fi

            # Handle EPP
            if [ "$EPP_AVAILABLE" -eq 1 ]; then
                if check_epp "default"; then
                    set_epp "default"
                elif check_epp "performance"; then
                    set_epp "performance"
                fi
            fi
            ;;
        "powersaver")
            set_governor "powersave"
            if [ "$EPP_AVAILABLE" -eq 1 ]; then
                if check_epp "power"; then
                    set_epp "power"
                fi
            fi
            ;;
        *)
            ;;
    esac
}

case "$1" in
    ac)
        POWER_MODE=$(cat /var/tmp/power_mode 2>/dev/null)
        if [ -z "$POWER_MODE" ]; then
            POWER_MODE="$(/usr/bin/batocera-settings-get-master global.powermode)"
            if [ -z "${POWER_MODE}" ]; then
                set_default
            fi
        fi
        handle_powermode "$POWER_MODE"
        ;;
    battery)
        POWER_MODE="$(/usr/bin/batocera-settings-get-master global.batterymode)"
        if [ -z "$POWER_MODE" ]; then
            POWER_MODE="balanced"
        fi
        handle_powermode "$POWER_MODE"
        ;;
    highperformance|balanced|powersaver)
        handle_powermode "$1"
        ;;
    default)
        set_default
        ;;
    *)
        echo "Invalid input. Usage: $0 [ac|battery|default|highperformance|balanced|powersaver]"
        exit 1
        ;;
esac

exit 0
